﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Globalization;
using System.IO;
using SETTINGS = maranov.TeaTimer.Properties.Settings;

namespace maranov.TeaTimer
{
    public partial class ApplicationMainForm : Form
    {
        public ApplicationMainForm()
        {
            InitializeComponent();

            // Popisky tlačítek
            EmptyTimeLabel(Label_Time);
            SetCustomRangeButtonLabel();
            SetRangeButtonLabel(Button_FixedRange1, SETTINGS.Default.Timer1_MinMinutes, SETTINGS.Default.Timer1_MaxMinutes);
            SetRangeButtonLabel(Button_FixedRange2, SETTINGS.Default.Timer2_MinMinutes, SETTINGS.Default.Timer2_MaxMinutes);
            SetRangeButtonLabel(Button_FixedRange3, SETTINGS.Default.Timer3_MinMinutes, SETTINGS.Default.Timer3_MaxMinutes);
            SetRangeButtonLabel(Button_FixedRange4, SETTINGS.Default.Timer4_MinMinutes, SETTINGS.Default.Timer4_MaxMinutes);

            // Přidělení ikony zvolenému typu zvukového upozornění
            switch ((AlertSound)Enum.Parse(typeof(AlertSound), SETTINGS.Default.AlertSoundType))
            {
                case AlertSound.None:
                    HighlightAlertContextMenuOption(ContextMenu_AlertSound_NoSound);
                    break;
                case AlertSound.Beep:
                    HighlightAlertContextMenuOption(ContextMenu_AlertSound_Beep);
                    break;
                case AlertSound.Exclamation:
                    HighlightAlertContextMenuOption(ContextMenu_AlertSound_Exclamation);
                    break;
                case AlertSound.Custom:
                    HighlightAlertContextMenuOption(ContextMenu_AlertSound_Custom);
                    break;
                default:
                    break;
            }

            // Časovače
            // Tik
            TeaTimer = new TeaTimer(SETTINGS.Default.Timer_TickIntervalMiliseconds);
            TeaTimer.Tick += new EventHandler<TickEventArgs>(
                delegate(object sender, TickEventArgs e)
                {
                    try
                    {
                        Invoke(new EventHandler<TickEventArgs>(TeaTimer_Tick), new object[] { sender, e });
                    }
                    catch (ObjectDisposedException) { }
                });
            // Vypršení
            TeaTimer.TimeUp += new EventHandler<EventArgs>(
                delegate(object sender, EventArgs e)
                {
                    try
                    {
                        Invoke(new EventHandler<EventArgs>(TeaTimer_TimeUp), new object[] { sender, e });
                    }
                    catch (ObjectDisposedException) { }
                });
            
            // Poskytovatel zvukového upozornění
            Alert = new SoundAlert(SETTINGS.Default.MaximumAlertPlaybackTimeSeconds);
            Alert.AlertSoundType = (AlertSound)Enum.Parse(typeof(AlertSound), SETTINGS.Default.AlertSoundType);
            Alert.CustomSoundFilePath = SETTINGS.Default.CustomAlertSoundFile;
            
            // Reakce na změnu nastavení
            SETTINGS.Default.SettingChanging += new System.Configuration.SettingChangingEventHandler(
                delegate(object sender, System.Configuration.SettingChangingEventArgs e)
                {
                    // Nastavení nově zvoleného zvukového upozornění
                    if (e.SettingName == "AlertSoundType")
                    {
                        AlertSound newType = (AlertSound)Enum.Parse(typeof(AlertSound), e.NewValue.ToString());
                        Alert.AlertSoundType = newType;
                    }
                    else if (e.SettingName == "CustomAlertSoundFile")
                    {
                        Alert.AlertSoundType = AlertSound.Custom; // Ověření
                        Alert.CustomSoundFilePath = e.NewValue.ToString();
                    }
                });

            // Další
            About = new ApplicationAboutBox();
            TaskbarProgressBarController = new NormalWindows7TaskbarProgressBar(this.Handle);
        }

        /// <summary>
        /// Použitý časovač
        /// </summary>
        private TeaTimer TeaTimer;

        /// <summary>
        /// Zvukové upozornění
        /// </summary>
        private SoundAlert Alert;

        /// <summary>
        /// AboutBox
        /// </summary>
        private ApplicationAboutBox About;

        /// <summary>
        /// Windows 7 Progress Bar integrovaný do Hlavního panelu - zbývající čas.
        /// </summary>
        NormalWindows7TaskbarProgressBar TaskbarProgressBarController;

        /// <summary>
        /// Nastaví popisek na tlačítku "od-do".
        /// </summary>
        /// <param name="timerButton">Tlačítko</param>
        /// <param name="from">Od (min)</param>
        /// <param name="to">Do (min)</param>
        private void SetRangeButtonLabel(Button timerButton, int from, int to)
        {
            if (from < to)
            {
                timerButton.Text = from.ToString("##") + "-" + to.ToString("##") + " min";
            }
            else
            {
                timerButton.Text = to.ToString("##") + "-" + from.ToString("##") + " min";
            }
        }

        /// <summary>
        /// Nastaví popisek uživatelsky nastavitelného tlačítka.
        /// </summary>
        private void SetCustomRangeButtonLabel()
        {
            SetRangeButtonLabel(Button_CustomRange, (int)(NumericUpDown_CustomTimerMinimum.Value), (int)(NumericUpDown_CustomTimerMaximum.Value));
        }

        /// <summary>
        /// Nastavení popisky ve tvaru času.
        /// </summary>
        /// <param name="minutes"></param>
        /// <param name="seconds"></param>
        /// <param name="label"></param>
        private void SetTimeLabel(int minutes, int seconds, Label label)
        {
            if (minutes <= 0)
            {
                minutes = 0;
            }
            if (seconds <= 0)
            {
                seconds = 0;
            }

            label.Text = minutes.ToString("00") + ":" + seconds.ToString("00");
        }

        /// <summary>
        /// Reset popisky ve tvaru času.
        /// </summary>
        /// <param name="label"></param>
        private void EmptyTimeLabel(Label label)
        {
            label.Text = "--:--";
        }

        /// <summary>
        /// Zastaví odpočet a přejde do neinicializovaného stavu.
        /// </summary>
        void StopTheTimer()
        {
            Label_Time.ForeColor = SystemColors.ControlText;

            TeaTimer.Stop();
            Alert.StopPlayback();

            Label_ExceededTime.Visible = false;
            Label_Overtime.Visible = false;
            Button_Stop.Visible = false;

            TaskbarProgressBarController.StopProgressBar();

            // Extra vynulování
            EmptyTimeLabel(Label_Time);
            EmptyTimeLabel(Label_ExceededTime);
        }

        /// <summary>
        /// Nastaví a spustí časovače.
        /// Časovače pojedou náhodný počet sek. v intervalu min-max.
        /// </summary>
        /// <param name="min"></param>
        /// <param name="max"></param>
        private void StartTheTimer(int min, int max)
        {
            StopTheTimer();
            Button_Stop.Visible = true;
            int totalSeconds = TeaTimer.Start(min, max);
            TaskbarProgressBarController.StartProgressBar((uint)totalSeconds);
        }

        /// <summary>
        /// Nastavení vlastního rozsahu hodnot.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CustomRangeValues_ValueChanged(object sender, EventArgs e)
        {
            SetCustomRangeButtonLabel();
        }

        /// <summary>
        /// Kliknutí na tlačítko s fixní hodnotou 1/4.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_FixedRange1_Click(object sender, EventArgs e)
        {
            StartTheTimer(
                SETTINGS.Default.Timer1_MinMinutes,
                SETTINGS.Default.Timer1_MaxMinutes);
        }

        /// <summary>
        /// Kliknutí na tlačítko s fixní hodnotou 2/4.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_FixedRange2_Click(object sender, EventArgs e)
        {
            StartTheTimer(
                SETTINGS.Default.Timer2_MinMinutes,
                SETTINGS.Default.Timer2_MaxMinutes);
        }

        /// <summary>
        /// Kliknutí na tlačítko s fixní hodnotou 3/4.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_FixedRange3_Click(object sender, EventArgs e)
        {
            StartTheTimer(
                SETTINGS.Default.Timer3_MinMinutes,
                SETTINGS.Default.Timer3_MaxMinutes);
        }

        /// <summary>
        /// Kliknutí na tlačítko s fixní hodnotou 4/4.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_FixedRange4_Click(object sender, EventArgs e)
        {
            StartTheTimer(
                SETTINGS.Default.Timer4_MinMinutes,
                SETTINGS.Default.Timer4_MaxMinutes);
        }

        /// <summary>
        /// Kliknutí na tlačítko s nastavitelnou hodnotou.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_CustomRange_Click(object sender, EventArgs e)
        {
            if (NumericUpDown_CustomTimerMinimum.Value <= NumericUpDown_CustomTimerMaximum.Value)
            {
                StartTheTimer((int)NumericUpDown_CustomTimerMinimum.Value, (int)NumericUpDown_CustomTimerMaximum.Value);
            }
            else
            {
                StartTheTimer((int)NumericUpDown_CustomTimerMaximum.Value, (int)NumericUpDown_CustomTimerMinimum.Value);
            }
        }

        /// <summary>
        /// Vypršení časovače (upozornění).
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TeaTimer_TimeUp(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.Focus();

            Label_Time.ForeColor = Color.DarkRed;

            Alert.Play();
        }

        /// <summary>
        /// Tik časovače (zobrazení času/průběhu).
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TeaTimer_Tick(object sender, TickEventArgs e)
        {
            if (!e.Overtime)
            {
                SetTimeLabel(e.Remaining.Minutes, e.Remaining.Seconds, Label_Time);
                TaskbarProgressBarController.UpdateProgressBar((uint)e.Remaining.TotalSeconds);
            }
            else
            {
                TaskbarProgressBarController.StopProgressBar();
                // Zobrazení přesčasu je zpožděno
                if (e.Remaining.TotalSeconds < -SETTINGS.Default.Overtime_DelaySeconds)
                {
                    Label_Overtime.Visible = true;
                    Label_ExceededTime.Visible = true;

                    SetTimeLabel(-e.Remaining.Minutes, -e.Remaining.Seconds, Label_ExceededTime);

                    // Maximální hodnota přesčasu
                    if (e.Remaining.TotalMinutes <= -SETTINGS.Default.Overtime_LimitMinutes)
                    {
                        StopTheTimer();
                    }
                }
            }
        }

        /// <summary>
        /// Zobrazení/skrytí menu s nápovědou.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Help_Click(object sender, EventArgs e)
        {
            if (!ContextMenu_Help.Visible)
            {
                ContextMenu_Help.Show(
                    Button_Help,
                    new Point(0, Button_Help.Size.Height));
            }
            else
            {
                ContextMenu_Help.Hide();
            }
        }

        /// <summary>
        /// Zobrazení/skrytí menu pro zvolení výstražného zvuku.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Alert_Click(object sender, EventArgs e)
        {
            if (!ContextMenu_AlertSound.Visible)
            {
                ContextMenu_AlertSound.Show(
                    Button_Alarm,
                    new Point(0, Button_Alarm.Size.Height));
            }
            else
            {
                ContextMenu_AlertSound.Hide();
            }
        }

        /// <summary>
        /// Kliknutí na "Stop" - zastavení veškeré aktivity.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Stop_Click(object sender, EventArgs e)
        {
            StopTheTimer();
        }

        /// <summary>
        /// Uzavření formuláře - vypnutí aplikace.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ApplicationForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            StopTheTimer();
            // Uložení nanázaných hodnot - uživatelský timer
            SETTINGS.Default.Save();
        }

        /// <summary>
        /// Menu výběru zvukového upozornění - kliknutí na "Vlastní...".
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenu_AlertSound_Custom_Click(object sender, EventArgs e)
        {
            OpenFileDialog_CustomSound.ShowDialog();
        }

        /// <summary>
        /// Dokončení výběru vlastního výstražného zvuku v dialogu.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenFileDialog_CustomSound_FileOk(object sender, CancelEventArgs e)
        {
            string selectedFile = OpenFileDialog_CustomSound.FileName;
            if (SoundAlert.IsSupportedFileExtension(Path.GetExtension(selectedFile)))
            {
                SETTINGS.Default.CustomAlertSoundFile = selectedFile;
                SETTINGS.Default.AlertSoundType = AlertSound.Custom.ToString();
                HighlightAlertContextMenuOption(ContextMenu_AlertSound_Custom);
            }
        }

        /// <summary>
        /// Menu výběru zvukového upozornění - kliknutí na "Výstraha".
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenu_AlertSound_Exclamation_Click(object sender, EventArgs e)
        {
            SETTINGS.Default.AlertSoundType = AlertSound.Exclamation.ToString();
            HighlightAlertContextMenuOption(ContextMenu_AlertSound_Exclamation);
        }

        /// <summary>
        /// Menu výběru zvukového upozornění - kliknutí na "Pípnutí".
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenu_AlertSound_Beep_Click(object sender, EventArgs e)
        {
            SETTINGS.Default.AlertSoundType = AlertSound.Beep.ToString();
            HighlightAlertContextMenuOption(ContextMenu_AlertSound_Beep);
        }

        /// <summary>
        /// Menu výběru zvukového upozornění - kliknutí na "Bez zvuku".
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenu_AlertSound_NoSound_Click(object sender, EventArgs e)
        {
            SETTINGS.Default.AlertSoundType = AlertSound.None.ToString();
            HighlightAlertContextMenuOption(ContextMenu_AlertSound_NoSound);
        }

        /// <summary>
        /// Provede zvýraznění vybrané/aktivní položky v menu pro výběr zvukového upozornění.
        /// Ostatní položky (předchozí zvýrazněná položka) jsou automaticky znevýrazněny.
        /// </summary>
        /// <param name="highlighed">Zvýrazněná položka</param>
        private void HighlightAlertContextMenuOption(ToolStripItem highlighed)
        {
            foreach (var item in ContextMenu_AlertSound.Items)
            {
                if (item is ToolStripItem)
                {
                    ((ToolStripItem)item).Image = null;
                }
            }
            highlighed.Image = Properties.Resources.preferences;
        }

        /// <summary>
        /// Menu nápovědy - kliknutí na "O programu...".
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenu_Help_About_Click(object sender, EventArgs e)
        {
            About.ShowDialog();
        }

        /// <summary>
        /// Menu nápovědy - kliknutí na "Nápověda...".
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenu_Help_Help_Click(object sender, EventArgs e)
        {
            try
            {
                string path;
                // Existující lokalizace nápovědy
                if (Thread.CurrentThread.CurrentUICulture.Name == "cs-CZ" ||
                    Thread.CurrentThread.CurrentUICulture.Name == "cs")
                {
                    path = SETTINGS.Default.HelpPath_CS;
                }
                else
                {
                    path = SETTINGS.Default.HelpPath;
                }

                System.Diagnostics.Process.Start(path);
            }
            catch { }
        }
    }
}
